home *** CD-ROM | disk | FTP | other *** search
/ Alde ADA 1: #1 / CCCC 8804 Volume 1 Number 1 - Alde.iso / C / MISC / FUNC / PROFF.ARC / PXXPARSE.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-02-21  |  12.8 KB  |  524 lines

  1. #include <stdio.h>
  2. #include <ctype.h>
  3. #include "proff.h"
  4. #include "debug.h"
  5. #include "lextab.h"
  6.  
  7. #define RUNOFF  1
  8.  
  9. char literal = NO;                     /* literal flag              */
  10.  
  11. /*
  12.  * command - perform formatting command
  13.  *
  14.  */
  15. command(buf)
  16. char buf[];
  17. {
  18.    char token[MAXTOK], xtoken[MAXTOK], variable[MAXTOK], *defn;
  19.    char special[MAXTOK], *strsave(char *);
  20.    int argtyp, ct, at, spval, i, flags;
  21.    register int val, n, rest;
  22.    char onflag = FALSE;
  23.    char offlag = FALSE;
  24.    struct lexlist *xp, *remove_item(char *, struct lexlist **);
  25.  
  26.    dovar(tbuf1, buf);                  /* use scratch buffer to expand variables */
  27.    strcpy(buf, tbuf1);
  28.  
  29.    i = 1;
  30.    n = getwrd(buf, &i, token);         /* get the command token */
  31.    rest = i;                           /* remaining string */
  32.    ct = comtype(token, n, &defn, &flags);
  33.    if (ct == UNKNOWN)
  34.       return;
  35.    if (literal && ct != ELT)
  36.    {                                   /* ignore while literal  */
  37.       put(buf);
  38.       return;
  39.    }
  40.  
  41. #ifdef DOUBLEWORD
  42.    if (flags == 2)
  43.    {                                   /* check for 2-word command */
  44.       n = getwrd(buf, &i, xtoken);
  45.       if (n == 0)
  46.       {
  47.          fprintf(stderr, "%c%s what ?\n", cchar, token);
  48.          return;
  49.       }
  50.       if ((at = comtype(xtoken, n, &defn, &flags)) == UNKNOWN)
  51.       {
  52.          fprintf(stderr, "%c%s %s unknown.\n", cchar, token, xtoken);
  53.          return;
  54.       }
  55.       else
  56.          ct += at;
  57.    }
  58. #endif
  59.  
  60.    doesc(buf, variable, MAXLINE);      /* expand escapes */
  61.    n = getarg(buf, &i, xtoken);        /* first parameter */
  62.    argtyp = '\n';                      /* defaulted ** cludge ** */
  63.    val = 0;
  64.    if (n > 0)
  65.    {
  66.       if (*xtoken == '+' || *xtoken == '-')
  67.       {
  68.          argtyp = *xtoken;
  69.          val = atoi(xtoken + 1);
  70.       }
  71.       else if (isdigit(*xtoken))
  72.       {
  73.          argtyp = 0;
  74.          val = atoi(xtoken);
  75.       }
  76.       else
  77.       {
  78.          /* check some common flags */
  79.          if (strcmp("on", xtoken) == 0)
  80.             onflag = TRUE;
  81.          else if (strcmp("off", xtoken) == 0)
  82.             offlag = TRUE;
  83.       }
  84.    }
  85.  
  86.    switch (ct)
  87.    {
  88.  
  89.    case MACRO:
  90.       eval(buf, defn);
  91.       break;
  92.    case FI:
  93.       brk();
  94.       fill = YES;
  95.       break;
  96.    case NF:
  97.       brk();
  98.       fill = NO;
  99.       break;
  100.    case BR:
  101.       brk();
  102.       break;
  103.    case LS:
  104.       set(&lsval, val, argtyp, 1, 1, HUGE);
  105.       break;
  106.    case CE:
  107.       brk();
  108.       if (onflag)
  109.          CEon = TRUE;
  110.       else
  111.       if (offlag)
  112.       {
  113.          CEon = FALSE;
  114.          ceval = 0;                    /* reset */
  115.       }
  116.       else
  117.          set(&ceval, val, argtyp, 1, 0, HUGE);
  118.       break;
  119.    case UL:
  120.       if (onflag)
  121.       {
  122.          ULon = TRUE;
  123.          break;
  124.       }
  125.       else if (offlag)
  126.       {
  127.          ULon = FALSE;
  128.          ulval = 0;                    /* reset */
  129.          break;
  130.       }
  131.       else
  132.          set(&ulval, val, argtyp, 0, 1, HUGE);
  133.  
  134.       if (!isdigit(*xtoken))
  135.       {
  136.          if (strcmp("all", xtoken) == 0)
  137.          {
  138.             ulblnk = '_';
  139.             ulval = 0;
  140.          }
  141.          else if (strcmp("words", xtoken) == 0)
  142.          {
  143.             ulblnk = ' ';
  144.             ulval = 0;
  145.          }
  146.       }
  147.       break;
  148.    case BD:
  149.       if (bolding == YES)
  150.       {
  151.          if (onflag)
  152.             BDon = TRUE;
  153.          else if (offlag)
  154.          {
  155.             BDon = FALSE;
  156.             boval = 0;                 /* reset */
  157.          }
  158.          else
  159.             set(&boval, val, argtyp, 0, 1, HUGE);
  160.       }
  161.       break;
  162.    case HE:
  163.       gettl(buf, ehead, ehlim);
  164.       gettl(buf, ohead, ohlim);
  165.       break;
  166.    case FO:
  167.       gettl(buf, efoot, eflim);
  168.       gettl(buf, ofoot, oflim);
  169.       break;
  170.    case BP:
  171.       if (paging == NO)
  172.          break;
  173.       brk();
  174.       if (lineno > 0)
  175.          space(HUGE);
  176.       set(&curpag, val, argtyp, curpag + 1, -HUGE, HUGE);
  177.       newpag = curpag;
  178.       break;
  179.    case SP:
  180.       set(&spval, val, argtyp, 1, 0, HUGE);
  181.       space(spval);
  182.       break;
  183.    case IN:
  184.       brk();
  185.       set(&inval, val, argtyp, 0, 0, rmval - 1);
  186.       tival = inval;
  187.       break;
  188.    case RM:
  189.       set(&rmval, val, argtyp, PAGEWIDTH, tival + 1, HUGE);
  190.       break;
  191.    case TI:
  192.       brk();
  193.       set(&tival, val, argtyp, 0, 0, rmval);
  194.       break;
  195.    case LEX:                          /****/
  196.       if ((xp = remove_item(xtoken, (struct lexlist **)lextab)) != NULL)
  197.       {
  198.          if (getwrd(buf, &i, variable) != 0)
  199.             lexinstal(variable, xp->val, xp->flag, lextab);
  200.       }
  201.       else
  202.          fprintf(stderr, "%s undefined.\n", xtoken);
  203.       break;
  204.    case PN:                           /****/
  205.       if (strcmp(xtoken, "roman") == 0)
  206.          roman = TRUE;
  207.       else if (strcmp(xtoken, "arabic") == 0)
  208.          roman = FALSE;
  209.       else
  210.          fprintf(stderr, "%c%s does not have %s option.\n", cchar, token, xtoken);
  211.       break;
  212.    case IG:                           /****/
  213.       break;
  214.    case SET:                          /****/
  215.       if (n > 0)
  216.       {
  217.          if (isdigit(*xtoken))
  218.          {
  219.             fprintf(stderr, "illegal variable name %s\n", xtoken);
  220.             break;
  221.          }
  222.          *variable = '\0';
  223.          n = getarg(buf, &i, variable);
  224.          if (n <= 0)
  225.          {
  226.             fprintf(stderr, "%s: ", xtoken);
  227.             gets(variable);
  228.          }
  229.          if (*variable != '\0')
  230.             install(xtoken, variable, gentab);
  231.       }
  232.       else
  233.          fprintf(stderr, "%c%s needs a variable name.\n", cchar, token);
  234.       break;
  235.    case GET:                          /****/
  236.       if (n > 0)
  237.       {
  238.          if (isdigit(*xtoken))
  239.          {
  240.             fprintf(stderr, "illegal variable name %s\n", xtoken);
  241.             break;
  242.          }
  243.          *variable = '\0';
  244.          n = getarg(buf, &i, tbuf3);   /* using temp buf3 */
  245.          if (n > 0)
  246.          {
  247.             fprintf(stderr, "%s", tbuf3);
  248.             gets(variable);
  249.          }
  250.          if (*variable != '\0')
  251.             install(xtoken, variable, gentab);
  252.       }
  253.       else
  254.          fprintf(stderr, "%c%s needs a variable name.\n", cchar, token);
  255.       break;
  256.    case CL:                           /****/
  257.       if (argtyp == '\n')
  258.       {
  259.          clast->level = 0;
  260.          clast->str = NULL;
  261.       }
  262.       else
  263.       {
  264.          skipbl(buf, &i);
  265.          if (*(buf + i) == '\0')
  266.             break;                     /* no contents line here ! */
  267.          clast->level = val * 3;       /* level * indent          */
  268.          n = i;
  269.          while (*(buf + n) != '\n')
  270.             n++;
  271.          *(buf + n) = '\0';            /* destroy CR with a null  */
  272.          clast->str = strsave(buf + i);
  273.          clast->page = curpag;
  274.       }
  275.       clast->nextc = (struct clist *) malloc(sizeof(struct clist));
  276.       p_memoryus += sizeof(struct clist);
  277.       clast = clast->nextc;
  278.       clast->nextc = NULL;
  279.       break;
  280.    case PC:                           /****/
  281.       brk();
  282.       clast = chead;
  283.       while (clast->nextc != NULL)
  284.       {
  285.          if (clast->str == NULL)
  286.             put("\n");
  287.          else
  288.          {
  289.             tival = (int) clast->level + inval;
  290.             i = rmval - tival;
  291.             docline(variable, i, clast->str, clast->page);
  292.             put(variable);
  293.          }
  294.          clast = clast->nextc;
  295.       }
  296.       break;
  297.    case DBO:                          /****/
  298.       bolding = NO;
  299.       break;
  300.    case EBO:                          /****/
  301.       bolding = YES;
  302.       break;
  303.    case AP:                           /****/
  304.       autopar = YES;
  305.       break;
  306.    case NAP:                          /****/
  307.       autopar = NO;
  308.       break;
  309.    case SAV:                          /****/
  310.       brk();
  311.       save();
  312.       break;
  313.    case RST:                          /****/
  314.       brk();
  315.       restore();
  316.       break;
  317.    case NPA:                          /****/
  318.       paging = NO;
  319.       savpl = plval;
  320.       plval = HUGE;
  321.       bottom = plval - m3val - m4val;
  322.       break;
  323.    case PGI:                          /****/
  324.       bottom = lineno - 1;             /* force end-of-page */
  325.       brk();
  326.       plval = savpl;
  327.       break;
  328.    case LTR:                          /****/
  329.       brk();
  330.       if (save())
  331.       {
  332.          inval = 0;
  333.          rmval = 132;
  334.          autopar = NO;
  335.          lsval = 0;
  336.          fill = NO;
  337.          literal = YES;
  338.       }
  339.       break;
  340.    case ELT:                          /****/
  341.       restore();
  342.       literal = NO;
  343.       break;
  344.    case WR:                           /****/
  345.       brk();
  346.       getpstr(buf + rest, special);
  347.       defn = special;
  348.       while (*defn)
  349.          putchar(*defn++);
  350.       break;
  351.    case PL:
  352.       if (paging == NO)
  353.          break;
  354.       set(&plval, val, argtyp, PAGELEN, m1val + m2val + m3val + m4val + 1, HUGE);
  355.       bottom = plval - m3val - m4val;
  356.       break;
  357.    case PO:
  358.       set(&offset, val, argtyp, 0, 0, rmval - 1);
  359.       break;
  360.    case M1:
  361.       set(&m1val, val, argtyp, 3, 0, plval - m2val - m3val - m4val - 1);
  362.       break;
  363.    case M2:
  364.       set(&m2val, val, argtyp, 2, 0, plval - m1val - m3val - m4val - 1);
  365.       break;
  366.    case M3:
  367.       set(&m3val, val, argtyp, 2, 0, plval - m1val - m2val - m4val - 1);
  368.       bottom = plval - m3val - m4val;
  369.       break;
  370.    case M4:
  371.       set(&m4val, val, argtyp, 3, 0, plval - m1val - m2val - m3val - 1);
  372.       bottom = plval - m3val - m4val;
  373.       break;
  374.    case EH:
  375.       gettl(buf, ehead, ehlim);
  376.       break;
  377.    case OH:
  378.       gettl(buf, ohead, ohlim);
  379.       break;
  380.    case EF:
  381.       gettl(buf, efoot, eflim);
  382.       break;
  383.    case OF:
  384.       gettl(buf, ofoot, oflim);
  385.       break;
  386.    case CC:
  387.       cchar = *xtoken;
  388.       if (cchar == '\0' || cchar == '\n')
  389.          cchar = '.';
  390.       if ((lineno + val) > bottom && lineno <= bottom)
  391.       {
  392.          space(val);
  393.          lineno = 0;
  394.       }
  395.       break;
  396.    case EC:
  397.       genesc = *xtoken;
  398.       if (genesc == '\0' || genesc == '\n')
  399.          genesc = '_';
  400.       break;
  401.    case NE:
  402.       if ((lineno + val) > bottom && lineno <= bottom)
  403.       {
  404.          space(val);
  405.          lineno = 0;
  406.       }
  407.       break;
  408.    case BS:
  409.       set(&bsval, val, argtyp, 1, 0, HUGE);
  410.       break;
  411.    case JU:
  412.       rjust = YES;
  413.       break;
  414.    case NJ:
  415.       rjust = NO;
  416.       break;
  417.    case SO:
  418.       if (n <= 0)
  419.          return;
  420.       if (level + 1 == NFILES)
  421.          error("? SO commands nested too deeply.");
  422.       if ((infile[level + 1] = fopen(xtoken, "r")) != NULL)
  423.       {
  424.          level++;
  425.          if (verbose == YES)
  426. #ifdef rainbow
  427.             fprintf(stderr, "source \033[7m%s\033[0m\n", xtoken);
  428. #else
  429.             fprintf(stderr, "source %s\n", xtoken);
  430. #endif
  431.       }
  432.       else
  433.          fprintf(stderr, "%s: cannot open.\n", xtoken);
  434.       break;
  435.    case OU:                           /*****/
  436.       /* skip for now. */
  437.       break;
  438.  
  439.    case OE:                           /*****/
  440.       /* skip for now. */
  441.       break;
  442.  
  443.    case CU:
  444.       ulblnk = '_';
  445.       set(&ulval, val, argtyp, 0, 1, HUGE);
  446.       break;
  447.    case DE:
  448.       dodef(buf, infile[level]);
  449.       break;
  450.    case NR:
  451.       if (n <= 0)
  452.          return;
  453.       if (*xtoken < 'a' || *xtoken > 'z')
  454.          error("invalid number register [%c].", *xtoken);
  455.       val = getval(buf, &i, &argtyp);
  456.       set(&nr[xtoken[0] - 'a'], val, argtyp, 0, -HUGE, HUGE);
  457.       break;
  458.    case ST:
  459.       if (argtyp == '-')
  460.          spval = plval;
  461.       else
  462.          spval = 0;
  463.       set(&spval, val, argtyp, 0, 1, bottom);
  464.       if (spval > lineno && lineno == 0)
  465.          phead();
  466.       if (spval > lineno)
  467.          space(spval - lineno);
  468.       break;
  469.    case RESET:                        /****/
  470.       finit();
  471.       break;
  472.    default:
  473.       error("? Botch in command.");
  474.       break;
  475.    }
  476. }
  477.  
  478. /*
  479.  * comtype - decode the command type
  480.  *
  481.  */
  482. int comtype(buf, siz, defn, flags)
  483. char buf[];
  484. int siz;
  485. char **defn;
  486. int *flags;
  487. {
  488.    struct hashlist *np, *lookup(char *, struct hashlist **);
  489.    struct lexlist *xp;
  490.    extern struct lexlist *lexlook();
  491.    int i, comtyp;
  492.    char c1, c2;
  493.  
  494. #ifdef DEBUG
  495.    printf("comtype: %s (token)\n", token1);
  496. #endif
  497.  
  498.    if ((np = lookup(buf, macrotab)) != NULL)
  499.    {
  500.       *defn = np->def;
  501.       return (MACRO);
  502.    }
  503.    comtyp = UNKNOWN;
  504.  
  505.    if (*buf == '#' || *buf == '!')
  506.       return (comtyp);
  507.  
  508.    if ((xp = lexlook(buf, lextab)) != NULL)
  509.       if (onlyrunoff && (xp->flag != RUNOFF))
  510.       {
  511.          fprintf(stderr, "%c%s is not a runoff command.\n", cchar, buf);
  512.          return (UNKNOWN);
  513.       }
  514.       else
  515.       {
  516.          comtyp = xp->val;
  517.          *flags = xp->flag;
  518.       }
  519.  
  520.    if (comtyp == UNKNOWN)
  521.       fprintf(stderr, "unknown command %c%s\n", cchar, buf);
  522.    return (comtyp);
  523. }
  524.